﻿using Colorful.Furniture.EnterpriseManagement;
using Colorful.Furniture.Permissions;
using FreeSql.Internal.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Users;

namespace Colorful.Furniture.PermissionManagement;

/// <summary>
///   当前用户权限提供者
/// </summary>
[ExposeServices(typeof(IDataPermissionProvider))]
public class CurrentUserPermissionProvider : IDataPermissionProvider
{
    private readonly ICurrentUser _currentUser;
    private readonly ILogger<CurrentUserPermissionProvider> _logger;

    public CurrentUserPermissionProvider(
        ICurrentUser currentUser,
        ILogger<CurrentUserPermissionProvider> logger)
    {
        _currentUser = currentUser;
        _logger = logger;
    }

    /// <summary>
    ///  类型
    /// </summary>
    public int Type => 1;

    /// <summary>
    ///  获取权限点
    /// </summary>
    /// <returns></returns>
    public async Task<List<Guid>> GetPermissionPointsAsync(DataPermissionContext context)
    {
        _logger.LogInformation("[当前用户]权限提供：1条数据");

        return await Task.FromResult(!_currentUser.Id.HasValue
            ? new List<Guid>()
            : new List<Guid> { _currentUser.Id.Value });
    }
}

/// <summary>
///  当前部门
/// </summary>
[ExposeServices(typeof(IDataPermissionProvider))]
public class CurrentDepartmentPermissionProvider : IDataPermissionProvider
{
    private readonly ICurrentUser _currentUser;
    private readonly IFreeSql _freeSql;
    private readonly ILogger<CurrentDepartmentAllPermissionProvider> _logger;

    public CurrentDepartmentPermissionProvider(
        IFreeSql freeSql,
        ICurrentUser currentUser,
        ILogger<CurrentDepartmentAllPermissionProvider> logger)
    {
        _freeSql = freeSql;
        _currentUser = currentUser;
        _logger = logger;
    }

    /// <summary>
    ///  类型
    /// </summary>
    public int Type => 2;

    /// <summary>
    ///  数据权限点
    /// </summary>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<List<Guid>> GetPermissionPointsAsync(DataPermissionContext context)
    {
        var userId = _currentUser.Id;

        //获取当前用户所在机构下的所有用户id集合
        var userDepartmentWithUserIdList = await _freeSql.Select<SysManager, Department, SysManager>()
            .InnerJoin(x => x.t1.DepartmentId == x.t2.Id)
            .LeftJoin(x => x.t2.Id == x.t3.DepartmentId)
            .Where(x => x.t1.Id == userId)
            .ToListAsync(x => x.t3.Id);

        _logger.LogInformation($"[当前部门]权限提供：{userDepartmentWithUserIdList.Count} 条数据");

        return userDepartmentWithUserIdList;
    }
}

/// <summary>
///  当前部门以及下级所有部门
/// </summary>
[ExposeServices(typeof(IDataPermissionProvider))]
public class CurrentDepartmentAllPermissionProvider : IDataPermissionProvider
{
    private readonly ICurrentUser _currentUser;
    private readonly IFreeSql _freeSql;
    private readonly ILogger<CurrentDepartmentAllPermissionProvider> _logger;

    public CurrentDepartmentAllPermissionProvider(
        ICurrentUser currentUser,
        IFreeSql freeSql,
        ILogger<CurrentDepartmentAllPermissionProvider> logger)
    {
        _currentUser = currentUser;
        _freeSql = freeSql;
        _logger = logger;
    }

    /// <summary>
    ///  类型
    /// </summary>
    public int Type => 3;

    /// <summary>
    ///  获取数据权限点
    /// </summary>
    /// <returns></returns>
    public async Task<List<Guid>> GetPermissionPointsAsync(DataPermissionContext context)
    {
        var userId = _currentUser.Id;

        //获取当前用户所在部门
        var userDepartment = await _freeSql.Select<SysManager, Department>()
            .InnerJoin(x => x.t1.DepartmentId == x.t2.Id)
            .Where(x => x.t1.Id == userId)
            .FirstAsync(x => new { x.t2.DepartId });

        var departmentUserList = await _freeSql.Select<SysManager, Department>()
            .InnerJoin(x => x.t1.DepartmentId == x.t2.Id)
            .Where(x => x.t2.ClassId.Contains($",{userDepartment.DepartId},"))
            .ToListAsync(x => x.t1.Id);

        _logger.LogInformation($"[当前部门以及下级所有部门]权限提供：{departmentUserList.Count} 条数据");

        return departmentUserList;
    }
}

/// <summary>
///  跨级部门
/// </summary>
[ExposeServices(typeof(IDataPermissionProvider))]
public class CrossLevelDepartmentPermissionProvider : IDataPermissionProvider
{
    private readonly IFreeSql _freeSql;
    private readonly ILogger<CrossLevelDepartmentPermissionProvider> _logger;

    public CrossLevelDepartmentPermissionProvider(IFreeSql freeSql,
        ILogger<CrossLevelDepartmentPermissionProvider> logger)
    {
        _freeSql = freeSql;
        _logger = logger;
    }

    /// <summary>
    ///  类型
    /// </summary>
    public int Type => 4;

    /// <summary>
    ///  获取数据权限点
    /// </summary>
    /// <returns></returns>
    public async Task<List<Guid>> GetPermissionPointsAsync(DataPermissionContext context)
    {
        if (!context.CrossLevelDepartmentIdList.Any())
            return new List<Guid>();

        //获取当前用户所在机构下的所有用户id集合
        var userDepartmentWithUserIdList = await _freeSql.Select<Department, SysManager>()
            .InnerJoin(x => x.t1.Id == x.t2.DepartmentId)
            .Where(x => context.CrossLevelDepartmentIdList.Contains(x.t1.DepartId))
            .ToListAsync(x => x.t2.Id);

        _logger.LogInformation($"[跨级部门]权限提供：{userDepartmentWithUserIdList.Count} 条数据");

        return userDepartmentWithUserIdList;
    }
}
/// <summary>
///  跨级部门以及下级所有的人员
/// </summary>
[ExposeServices(typeof(IDataPermissionProvider))]
public class CrossLevelDepartmentAllPermissionProvider : IDataPermissionProvider
{
    private readonly IFreeSql _freeSql;
    private readonly ILogger<CrossLevelDepartmentAllPermissionProvider> _logger;

    public CrossLevelDepartmentAllPermissionProvider(
        IFreeSql freeSql,
        ILogger<CrossLevelDepartmentAllPermissionProvider> logger)
    {
        _freeSql = freeSql;
        _logger = logger;
    }

    /// <summary>
    ///  类型
    /// </summary>
    public int Type => 5;

    /// <summary>
    ///  获取权限点
    /// </summary>
    /// <param name="context">数据权限上下文</param>
    /// <returns></returns>
    public async Task<List<Guid>> GetPermissionPointsAsync(DataPermissionContext context)
    {
        //动态筛选条件
        var dynamicFilterInfo = new DynamicFilterInfo
        {
            Filters = new List<DynamicFilterInfo>(),
            Logic = DynamicFilterLogic.Or
        };

        if (!context.CrossLevelDepartmentIdList.Any())
        {
            dynamicFilterInfo.Filters.Add(new DynamicFilterInfo
            {
                Field = $"{nameof(Department)}.{nameof(Department.DepartId)}",
                Operator = DynamicFilterOperator.Eq,
                Value = -9999
            });
        }
        else
        {
            foreach (var item in context.CrossLevelDepartmentIdList)
            {
                dynamicFilterInfo.Filters.Add(new DynamicFilterInfo
                {
                    Field = $"{nameof(Department)}.{nameof(Department.ClassId)}",
                    Operator = DynamicFilterOperator.Contains,
                    Value = $",{item},"
                });
            }
        }

        var departmentUserList = await _freeSql.Select<SysManager, Department>()
            .InnerJoin(x => x.t1.DepartmentId == x.t2.Id)
            .WhereDynamicFilter(dynamicFilterInfo)
            .ToListAsync(x => x.t1.Id);

        _logger.LogInformation($"[跨级部门]权限提供：{departmentUserList.Count} 条数据");

        return departmentUserList;
    }
}
